Here's an example which illustrates some C++ class syntactic symbols:
1: class Bass
2: : public Guitar,
3: public Amplifiable
4: {
5: public:
6: Bass()
7: : eString( new BassString( 0.105 )),
8: aString( new BassString( 0.085 )),
9: dString( new BassString( 0.065 )),
10: gString( new BassString( 0.045 ))
11: {
12: eString.tune( 'E' );
13: aString.tune( 'A' );
14: dString.tune( 'D' );
15: gString.tune( 'G' );
16: }
17: friend class Luthier;
18: };
As
in the previous example, line 1 has the
topmost-intro syntax. Here however, the brace that
opens a C++ class definition on line 4 is assigned the
class-open syntax. Note that in C++, classes,
structs, and unions are essentially equivalent syntactically (and
are very similar semantically), so replacing the
class keyword in the example above with
struct or union would still result in a
syntax of class-open for line 4 1. Similarly,
line 18 is assigned class-close syntax.
Line
2 introduces the inheritance list for the class so it is assigned
the inher-intro syntax, and line 3, which continues
the inheritance list is given inher-cont syntax.
Hitting C-c C-s on line 5 shows the following analysis:
((inclass 58) (access-label 58))
The primary syntactic symbol for this line is
access-label as this is a label keyword that
specifies access protection in C++. However, because this line is
also a top-level construct inside a class definition, the
analysis actually shows two syntactic symbols. The other
syntactic symbol assigned to this line is inclass.
Similarly, line 6 is given both inclass and
topmost-intro syntax:
((inclass 58) (topmost-intro 60))
Line 7 introduces a C++
member initialization list and as such is given
member-init-intro syntax. Note that in this case it
is not assigned inclass since this is not
considered a top-level construct. Lines 8 through 10 are all
assigned member-init-cont since they continue the
member initialization list started on line 7.
Line 11's analysis is a bit more complicated:
((inclass 58) (inline-open))
This line is assigned a syntax of both
inline-open and inclass because it
opens an in-class C++ inline method definition. This
is distinct from, but related to, the C++ notion of an inline
function in that its definition occurs inside an enclosing class
definition, which in C++ implies that the function should be
inlined. However, if the definition of the Bass
constructor appeared outside the class definition, the construct
would be given the defun-open syntax, even if the
keyword inline appeared before the method name, as
in:
1: class Bass
2: : public Guitar,
3: public Amplifiable
4: {
5: public:
6: Bass();
7: };
8:
9: inline
10: Bass::Bass()
11: : eString( new BassString( 0.105 )),
12: aString( new BassString( 0.085 )),
13: dString( new BassString( 0.065 )),
14: gString( new BassString( 0.045 ))
15: {
16: eString.tune( 'E' );
17: aString.tune( 'A' );
18: dString.tune( 'D' );
19: gString.tune( 'G' );
20: }
Returning
to the previous example, line 16 is given
inline-close syntax, while line 12 is given
defun-block-open syntax, and lines 13 through 15 are
all given statement syntax. Line 17 is interesting
in that its syntactic analysis list contains three elements:
((inclass 58) (topmost-intro 380) (friend))
The friend and inline-open syntactic
symbols are modifiers that do not have anchor positions.
Template definitions introduce yet another syntactic symbol:
1: ThingManager <int,
2: Framework::Callback *,
3: Mutex> framework_callbacks;
Here, line 1 is analyzed as a topmost-intro, but
lines 2 and 3 are both analyzed as
template-args-cont lines.
[1] This is the case even for C and
Objective-C. For consistency, structs in all supported
languages are syntactically equivalent to classes. Note however
that the keyword class is meaningless in C and
Objective-C.